#ifndef CORE_DEFAULT_COMMAND_SHEDULER_H_INCLUDED
#define CORE_DEFAULT_COMMAND_SHEDULER_H_INCLUDED

#include <Core/Commands.h>
#include <Core/Box/Transports.h>

#include <exception>
#include <boost/threadpool.hpp>

namespace Core {

/**
 * The DefaultCommandSchedulerParams, need for initialize DefaultCommandScheduler  
 */
struct DefaultCommandSchedulerParams {
	int concurrency;			// number of background threads
};

/**
 *
 */
class DefaultCommandScheduler : public BoxCore::IBoxCommandIFace {
public :
	explicit DefaultCommandScheduler(DefaultCommandSchedulerParams const & params);

	virtual ~DefaultCommandScheduler() throw ();

	virtual void initialize() throw (std::exception); 
	
	virtual bool spawn(
		SyncedCommandIOStreamPtr stream,
		BoxCore::IBoxCommandIFace::SpawnCompeletionFunc spawnCompeletion) throw ();

	virtual void interrupt(bool graceful) throw (); 
	
	virtual void run() throw (std::exception);

private :	
	void executeCommand(Core::ICommandPtr command,
		BoxCore::IBoxCommandIFace::SpawnCompeletionFunc spawnCompeletion,
        SyncedCommandIOStreamPtr stream) 
	{
		/*  Execute command logic sync/blocking after call SpawnCompeletionFunc 
			to set end of calls */
		command->execute();
		// TODO add error code in spawnCompeletion call
		spawnCompeletion(0, stream); 
	}

	boost::threadpool::pool m_scheduler; 			// Task pool for command execution
	DefaultCommandSchedulerParams const m_params;	// args
};

typedef boost::shared_ptr<DefaultCommandScheduler> DefaultCommandSchedulerPtr;

/**
 *
 */
void initializeDefaultCommandScheduler(DefaultCommandSchedulerParams const & params) throw (std::exception);

DefaultCommandSchedulerPtr defaultScheduler() throw (std::exception);

}

#endif

